package com.huluobo.a2111douyindemo.live;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;

import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import com.huluobo.a2111douyindemo.R;
import com.huluobo.a2111douyindemo.adapter.GiftAdapter;
import com.huluobo.a2111douyindemo.adapter.MessageAdapter;
import com.huluobo.a2111douyindemo.databinding.ActivityLiveBinding;
import com.huluobo.a2111douyindemo.utils.ImageLoader;
import com.huluobo.mvvm_base.mvvm.base.view.BaseMVVMActivity;
import com.huluobo.mvvm_base.mvvm.bean.FollowBeanResult;
import com.huluobo.mvvm_base.mvvm.bean.GiftBeanResult;
import com.huluobo.mvvm_base.mvvm.bean.Money;
import com.huluobo.mvvm_base.mvvm.bean.VideoBeanResult;
import com.huluobo.mvvm_base.mvvm.net.Const;
import com.hyphenate.EMCallBack;
import com.hyphenate.EMChatRoomChangeListener;
import com.hyphenate.EMMessageListener;
import com.hyphenate.EMValueCallBack;
import com.hyphenate.chat.EMChatRoom;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.chat.EMTextMessageBody;

import java.util.ArrayList;
import java.util.List;

import master.flame.danmaku.danmaku.model.BaseDanmaku;
import master.flame.danmaku.danmaku.model.IDanmakus;
import master.flame.danmaku.danmaku.model.android.DanmakuContext;
import master.flame.danmaku.danmaku.model.android.Danmakus;
import master.flame.danmaku.danmaku.parser.BaseDanmakuParser;


public class LiveActivity extends BaseMVVMActivity<ActivityLiveBinding, LiveViewModel> {
    private VideoBeanResult.VideoBean videoBean;

    //礼物的adapter
    private GiftAdapter giftAdapter;

    //礼物的数据源
    private List<GiftBeanResult.GiftBean> giftBeanList = new ArrayList<>();

    //选中的礼物
    private GiftBeanResult.GiftBean giftBean;

    //用户余额
    private Money money;

    //消息列表的adapter
    private MessageAdapter messageAdapter;

    //消息列表的数据源
    private List<MessageEntity> messageEntities = new ArrayList<>();

    @Override
    protected void initData() {

        //设置播放器的返回按钮隐藏
        dataBinding.liveGsyPlayer.getBackButton().setVisibility(View.GONE);

        //设置视频地址
        dataBinding.liveGsyPlayer.setUp(videoBean.getVideopath(), true, "");
        dataBinding.liveGsyPlayer.startPlayLogic();

        viewModel.followSuccess.observe(this, followBeanResult -> {
            if (followBeanResult.getCode() == 200) {
                ToastUtils.showLong(followBeanResult.getMessage());
                //修改关注状态
                dataBinding.liveBtnFollow.setText("已关注");
                //修改关注背景
                dataBinding.liveBtnFollow.setBackgroundResource(R.drawable.shape_red);
                //数组层面也需要修改为已关注状态,这样下次再点击才不会数据冲突,导致关注失败
                videoBean.setGuanzhu(1);
            } else {
                ToastUtils.showLong(followBeanResult.getMessage());
            }
        });

        viewModel.followFailed.observe(this, s -> {
            Log.i("TagA", "关注失败:" + s);
        });

        viewModel.noFollowSuccess.observe(this, followBeanResult -> {
            if (followBeanResult.getCode() == 200) {
                ToastUtils.showLong(followBeanResult.getMessage());
                //修改关注状态
                dataBinding.liveBtnFollow.setText("关注");
                //修改关注背景
                dataBinding.liveBtnFollow.setBackgroundResource(R.drawable.shape_alpha_black);
                //数组层面也需要修改为已关注状态,这样下次再点击才不会数据冲突,导致关注失败
                videoBean.setGuanzhu(0);
            } else {
                ToastUtils.showLong(followBeanResult.getMessage());
            }
        });

        viewModel.noFollowFailed.observe(this, s -> {
            Log.i("TagA", "取消关注失败:" + s);
        });

        viewModel.getGiftSuccess.observe(this, giftBeanResult -> {
            if (giftBeanResult.getCode() == 200) {
                giftBeanList.clear();
                giftBeanList.addAll(giftBeanResult.getData());
                giftAdapter.notifyDataSetChanged();
            } else {
                ToastUtils.showLong(giftBeanResult.getMessage());
            }
        });

        viewModel.getGiftFailed.observe(this, s -> {
            Log.i("tagA", "gifts:" + s);
        });

        viewModel.getMoneySuccess.observe(this, money -> {
            this.money = money;
            dataBinding.liveUserMoneyTv.setText("余额:" + money.money + "抖币");
        });

        viewModel.getMoneyFailed.observe(this, s -> {
            Log.i("tagA", "获取余额失败::" + s);
        });

    }

    @Override
    protected void initView() {
        videoBean = (VideoBeanResult.VideoBean) getIntent().getSerializableExtra("videoBean");

        //设置基本信息
        //头像
        ImageLoader.getInstance().loadCircleImage(this, videoBean.getHeadpath(), dataBinding.liveUserIconIv);
        //用户名
        dataBinding.liveUsernameTv.setText(videoBean.getAuthname());
        //关注状态
        dataBinding.liveBtnFollow.setText(videoBean.getGuanzhu() == 0 ? "关注" : "已关注");
        //设置关注按钮背景
        dataBinding.liveBtnFollow.setBackgroundResource(videoBean.getGuanzhu() == 0 ? R.drawable.shape_alpha_black :
                R.drawable.shape_red);
        //设置关注按钮点击事件,触发关注接口
        dataBinding.liveBtnFollow.setOnClickListener(v -> {
            if (videoBean.getGuanzhu() == 0) {
                //未关注,触发关注接口
                viewModel.followAuth(videoBean.getAuthname());
            } else {
                //已关注,触发取消关注接口
                viewModel.noFollowAuth(videoBean.getAuthname());
            }
        });

        //添加点赞动画图片
//        dataBinding.liveLikeView.addLikeImages(
        int[] resId = {
                R.drawable.ic_favorite_0,
                R.drawable.ic_favorite_1,
                R.drawable.ic_favorite_2,
                R.drawable.ic_favorite_3,
                R.drawable.ic_favorite_4,
                R.drawable.ic_favorite_5,
                R.drawable.ic_favorite_4,
                R.drawable.ic_favorite_3,
                R.drawable.ic_favorite_2,
                R.drawable.ic_favorite_1,
                R.drawable.ic_favorite_0
        };

        dataBinding.liveLikeView.setResId(resId);

        //点击触发点赞动画
        dataBinding.liveLikeIv.setOnClickListener(v -> {
            dataBinding.liveLikeView.addFavor();
        });

        //点击弹出弹幕输入框布局
        dataBinding.liveDanmuIv.setOnClickListener(v -> {
            dataBinding.liveDanmuLayoutLl.setVisibility(View.VISIBLE);
        });

        //初始化弹幕
        initDanmuView();

        //点击发送弹幕的事件
        dataBinding.liveDanmuSendIv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendDanmu();
            }
        });

        //礼物按钮点击事件
        dataBinding.liveGiftIv.setOnClickListener(v -> {
            openGiftLayout();
        });

        //礼物关闭按钮点击事件
        dataBinding.liveCloseTv.setOnClickListener(v -> {
            closeGiftLayout();
        });

        //初始化礼物列表
        dataBinding.liveGiftListRv.setLayoutManager(new GridLayoutManager(this, 5));
        giftAdapter = new GiftAdapter(giftBeanList);
        dataBinding.liveGiftListRv.setAdapter(giftAdapter);

        //礼物列表的点击事件
        giftAdapter.setOnItemClickListener((adapter, view, position) -> {
            giftBean = giftBeanList.get(position);//选中的礼物赋值
            //给选中的礼物赋值图片
            ImageLoader.getInstance().loadCircleImage(this, giftBean.getGiftpath(), dataBinding.liveGiftSelectIv);
            dataBinding.liveGiftNameTv.setText(giftBean.getGiftname());
        });

        //发送礼物的点击事件
        dataBinding.liveGiftSendBtn.setOnClickListener(v -> {
            sendGift();
        });

        //初始化聊天室列表
        messageAdapter = new MessageAdapter(messageEntities);
        dataBinding.liveChatRoomRv.setLayoutManager(new LinearLayoutManager(this));
        dataBinding.liveChatRoomRv.setAdapter(messageAdapter);

        //初始化环信聊天室
        initChatRoom();

        //消息按钮的点击事件
        dataBinding.liveInputTv.setOnClickListener(v -> {
            dataBinding.liveMsgLayoutLl.setVisibility(View.VISIBLE);
        });

        //消息发送按钮的点击事件
        dataBinding.liveMsgSendIv.setOnClickListener(v -> {
            sendTextMessage();
        });

    }

    //发送一条消息
    private void sendTextMessage() {
        if (dataBinding.liveMsgInputEt.getText().toString().length() != 0) {
            sendEMRoomMessage(Const.ROOM_ID, dataBinding.liveMsgInputEt.getText().toString());
        } else {
            ToastUtils.showLong("请输入聊天内容");
        }
    }

    //初始化环信聊天室
    private void initChatRoom() {
        //添加聊天室的消息监听器
        EMClient.getInstance().chatManager().addMessageListener(messageListener);
        //添加聊天室状态改变的监听器
        EMClient.getInstance().chatroomManager().addChatRoomChangeListener(chatRoomChangeListener);
        EMClient.getInstance().chatroomManager().joinChatRoom(Const.ROOM_ID, new EMValueCallBack<EMChatRoom>() {
            @Override
            public void onSuccess(EMChatRoom value) {
                Log.i("TagA", "初始化聊天室成功:");
            }

            @Override
            public void onError(int error, String errorMsg) {
                Log.i("TagA", "初始化聊天室失败:" + errorMsg + ",code:" + error);
            }
        });
    }

    //环信消息监听器,接收到消息时需要做什么事儿,目前,首先需要添加到消息列表中,刷新适配器,同时需要加入到弹幕中,发送一条弹幕
    private EMMessageListener messageListener = new EMMessageListener() {
        @Override
        public void onMessageReceived(List<EMMessage> messages) {
            //需要将接收到的消息添加到聊天室列表中,刷新适配器
            runOnUiThread(() -> {
                for (EMMessage emMessage : messages) {
                    String fromName = emMessage.getFrom();//拿到消息发送的用户名
                    //EMMessage中没有办法直接拿到消息内容,需要先拿到消息体然后转化
                    EMTextMessageBody messageBody = (EMTextMessageBody) emMessage.getBody();
                    //从消息体中拿到消息内容
                    String content = messageBody.getMessage();
                    //封装成自己的消息体bean类
                    MessageEntity message = new MessageEntity(fromName, content);
                    //聊天消息的数据源加入一条
                    messageEntities.add(message);
                    messageAdapter.notifyDataSetChanged();
                    //滚动到消息的最新位置
                    dataBinding.liveChatRoomRv.scrollToPosition(messageEntities.size() - 1);


                    //接收到消息,发送弹幕
                    //清理弹幕
                    dataBinding.liveDanmakuView.clear();
                    dataBinding.liveDanmakuView.removeAllDanmakus(true);

                    BaseDanmaku danmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
                    danmaku.text = content;
                    danmaku.textSize = 30;
                    danmaku.textColor = Color.WHITE;
                    danmaku.padding = 10;
                    danmaku.setTime(800);

                    //添加弹幕到视图中
                    dataBinding.liveDanmakuView.addDanmaku(danmaku);
                    dataBinding.liveDanmakuView.start();

                }
            });
        }
    };

    //聊天室改变监听器
    private EMChatRoomChangeListener chatRoomChangeListener = new EMChatRoomChangeListener() {
        @Override
        public void onChatRoomDestroyed(String roomId, String roomName) {

        }

        @Override
        public void onMemberJoined(String roomId, String participant) {
            //当用户进入直播间时,发送一条消息,比如:张三:进入聊天室了,舰长进入聊天室,更新数据源,在聊天列表上展示

            //再通过环信发送一条消息,让其他用户也能看到进入聊天室的信息
            sendEMRoomMessage(roomId, participant + "进入直播间了");
        }

        @Override
        public void onMemberExited(String roomId, String roomName, String participant) {
            sendEMRoomMessage(roomId, participant + "退出直播间了");
        }

        @Override
        public void onRemovedFromChatRoom(int reason, String roomId, String roomName, String participant) {

        }

        @Override
        public void onMuteListAdded(String chatRoomId, List<String> mutes, long expireTime) {

        }

        @Override
        public void onMuteListRemoved(String chatRoomId, List<String> mutes) {

        }

        @Override
        public void onWhiteListAdded(String chatRoomId, List<String> whitelist) {

        }

        @Override
        public void onWhiteListRemoved(String chatRoomId, List<String> whitelist) {

        }

        @Override
        public void onAllMemberMuteStateChanged(String chatRoomId, boolean isMuted) {

        }

        @Override
        public void onAdminAdded(String chatRoomId, String admin) {

        }

        @Override
        public void onAdminRemoved(String chatRoomId, String admin) {

        }

        @Override
        public void onOwnerChanged(String chatRoomId, String newOwner, String oldOwner) {

        }

        @Override
        public void onAnnouncementChanged(String chatRoomId, String announcement) {

        }
    };

    //往聊天室中发送一条消息
    private void sendEMRoomMessage(String roomId, String message) {
        //构建一条环信的消息
        EMMessage emMessage = EMMessage.createTextSendMessage(message, roomId);
        emMessage.setChatType(EMMessage.ChatType.ChatRoom);//设置消息类型为聊天室消息
        emMessage.setBody(new EMTextMessageBody(message));//构建消息体
        EMClient.getInstance().chatManager().sendMessage(emMessage);//发送消息到服务器
        //设置消息状态的回调,成功/失败/在发送中
        emMessage.setMessageStatusCallback(new EMCallBack() {
            @Override
            public void onSuccess() {
                runOnUiThread(() -> {
                    //创建消息实体类
                    MessageEntity messageEntity = new MessageEntity(EMClient.getInstance().getCurrentUser(), message);
                    //消息列表数据源插入一条消息
                    messageEntities.add(messageEntity);
                    //刷新适配器
                    messageAdapter.notifyDataSetChanged();
                    //滚动到聊天列表最下方
                    dataBinding.liveChatRoomRv.scrollToPosition(messageEntities.size() - 1);
                    //清空输入框
                    dataBinding.liveMsgInputEt.setText("");
                    //聊天布局隐藏
                    dataBinding.liveMsgLayoutLl.setVisibility(View.GONE);
                });
            }

            @Override
            public void onError(int code, String error) {
                Log.i("TagA", "发送消息失败:" + error + ",code:" + code);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //页面销毁时需要退出聊天室
        EMClient.getInstance().chatroomManager().leaveChatRoom(Const.ROOM_ID);
        //页面销毁时需要移除掉消息监听器
        EMClient.getInstance().chatManager().removeMessageListener(messageListener);
    }

    //发送礼物的方法
    private void sendGift() {
        //拿到用户余额
        //扣款的逻辑(账号余额是否充足->充足,余额足够 -> 扣款,更新UI,更新数据库中账号余额)
        //检查礼物发送时不能为空,余额也不能为空
        if (giftBean == null || money == null) {
            ToastUtils.showLong("请选择礼物,再点击发送");
            return;
        }
        //判断当前的余额是否小于礼物的价格,如果小于->余额不足
        if (money.money < giftBean.getPrice()) {
            ToastUtils.showLong("用户余额不足,请充值");
            return;
        }
        //准备更新余额,新的余额等于当前余额减去礼物价格
        float newMoney = money.money - giftBean.getPrice();
        //更新UI
        dataBinding.liveUserMoneyTv.setText("余额:" + newMoney + "抖币");
        //更新数据库中的余额
        money.money = newMoney;
        viewModel.updateUserMoney(money);


        //构建一个imageView承载礼物动画
        ImageView giftAnimView = new ImageView(this);
        //直接new的view,没有属性,它没有宽高,都需要设置一个宽高,但是,宽高不能直接给view来设置,需要使用Layout的LayoutParams来设置
        ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(200, 200);
        giftAnimView.setLayoutParams(params);

        //将构建好的imageView添加到布局上
        dataBinding.liveRootCl.addView(giftAnimView);
        //给imageView添加图片资源
        ImageLoader.getInstance().loadImage(this, giftBean.getGiftpath(), giftAnimView);

        //展示礼物动画
        int screenWidth = dataBinding.liveRootCl.getMeasuredWidth();//获取根布局的宽高
        int screenHeight = dataBinding.liveRootCl.getMeasuredHeight();

        ObjectAnimator translationY = ObjectAnimator.ofFloat(giftAnimView, "TranslationY", screenHeight,
                screenHeight / 3, screenHeight / 2);
        ObjectAnimator translationX = ObjectAnimator.ofFloat(giftAnimView, "TranslationX", screenWidth / 2,
                screenWidth / 3 * 2, screenWidth / 2, screenWidth / 3, screenWidth / 2);
        ObjectAnimator rotation = ObjectAnimator.ofFloat(giftAnimView, "Rotation", 0, 1080);
        ObjectAnimator scaleX = ObjectAnimator.ofFloat(giftAnimView, "ScaleX", 1, 2, 1, 3, 1, 2, 1);
        ObjectAnimator scaleY = ObjectAnimator.ofFloat(giftAnimView, "ScaleY", 1, 2, 1, 3, 1, 2, 1);
        ObjectAnimator alpha = ObjectAnimator.ofFloat(giftAnimView, "Alpha", 0.1f, 0.5f, 1.0f, 0.5f, 0.1f);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(3000);
        animatorSet.setInterpolator(new AccelerateDecelerateInterpolator());
        animatorSet.playTogether(translationX, translationY, rotation, scaleX, scaleY, alpha);

        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(@NonNull Animator animation, boolean isReverse) {
                super.onAnimationStart(animation, isReverse);
                //动画开始时,关闭礼物列表
                dataBinding.liveGiftLayoutCl.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) {
                super.onAnimationEnd(animation, isReverse);
                //动画结束移除礼物的imageView
                dataBinding.liveRootCl.removeView(giftAnimView);
            }
        });
        animatorSet.start();
    }

    //关闭礼物布局
    private void closeGiftLayout() {
        dataBinding.liveGiftLayoutCl.setVisibility(View.GONE);
    }

    //打开礼物布局
    private void openGiftLayout() {
        dataBinding.liveGiftLayoutCl.setVisibility(View.VISIBLE);
        //获取礼物列表
        viewModel.getGiftList();
        //拿到用户余额赋值
        viewModel.getUserMoney(SPUtils.getInstance().getString(Const.SP_USERNAME));
    }

    //弹幕上下文
    private DanmakuContext danmakuContext;

    //初始化弹幕
    private void initDanmuView() {
        //1.清理弹幕缓存
        dataBinding.liveDanmakuView.enableDanmakuDrawingCache(false);
        dataBinding.liveDanmakuView.clear();
        dataBinding.liveDanmakuView.removeAllDanmakus(true);

        //2.创建弹幕的上下文
        danmakuContext = DanmakuContext.create();

        //3.准备弹幕
        dataBinding.liveDanmakuView.prepare(new BaseDanmakuParser() {
            @Override
            protected IDanmakus parse() {
                return new Danmakus();
            }
        }, danmakuContext);
    }

    //发送弹幕
    private void sendDanmu() {
        //获取弹幕内容
        String danmuString = dataBinding.liveDanmuInputEt.getText().toString();
        if (TextUtils.isEmpty(danmuString)) {
            ToastUtils.showLong("请输入弹幕内容!");
            return;
        }

        //清理弹幕
        dataBinding.liveDanmakuView.clear();
        dataBinding.liveDanmakuView.removeAllDanmakus(true);

        //创建弹幕的实体
        BaseDanmaku danmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);//设置方向从右到左
        danmaku.text = danmuString;//弹幕内容
        danmaku.textSize = 30;//弹幕大小
        danmaku.textColor = Color.WHITE;//弹幕颜色
        danmaku.padding = 10;//弹幕的内边距
        danmaku.setTime(800);

        //添加弹幕到View中
        dataBinding.liveDanmakuView.addDanmaku(danmaku);
        dataBinding.liveDanmakuView.start();

        //清理输入框和隐藏输入框布局
        dataBinding.liveDanmakuView.postDelayed(() -> {
            dataBinding.liveDanmuInputEt.setText("");
            dataBinding.liveDanmuLayoutLl.setVisibility(View.GONE);
        }, 300);
    }

    @Override
    protected Class<LiveViewModel> getViewModel() {
        return LiveViewModel.class;
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_live;
    }
}